import { cn } from "./helpers/utils";
import type { Dayjs } from "dayjs";
import type { TaskProps, TaskMode, FlattenedTask } from "./types";
import GanttContext from "./context";
import { useEffect, useState, useCallback, useRef } from "react";
import Task from "./task-body/task";
import TaskHeader from "./task-header";
import Gantt from "./task-body/gantt";
import { flattenTasks, getInitialExpandedTasks } from "./helpers/utils";
import { GanttConsts } from "./constants";
import Split from "./components/split";
import { getTotalWidth } from "./helpers/time";
import dayjs from "dayjs";
import weekOfYear from "dayjs/plugin/weekOfYear";
import quarterOfYear from "dayjs/plugin/quarterOfYear";

// 扩展dayjs插件
dayjs.extend(weekOfYear);
dayjs.extend(quarterOfYear);

export interface GanttProps {
  title?: string;
  className?: string;
  taskList: TaskProps[];
  tasksStart: Dayjs;
  tasksEnd: Dayjs;
}

export default function TaskGantt(props: GanttProps) {
  const { className, taskList, title, tasksStart, tasksEnd } = props;
  const [tasks, setTasks] = useState<TaskProps[]>([]);
  const [flattenedTasks, setFlattenedTasks] = useState<FlattenedTask[]>([]);
  const [expandedTasks, setExpandedTasks] = useState<Set<string>>(new Set());
  const [taskMode, setTaskMode] = useState<TaskMode>("Day");
  const [hideTask, setHideTask] = useState<boolean>(false);
  const [hoverTaskId, setHoverTaskId] = useState<string>("");
  const [scrollTop, setScrollTop] = useState<number>(0);
  const [totalWidth, setTotalWidth] = useState<number>(0);

  // 滚动
  const [hScrollbarWidth, setHScrollbarWidth] = useState(0);
  const [hScrollbarLeft, setHScrollbarLeft] = useState(0);
  const [vScrollbarHeight, setVScrollbarHeight] = useState(0);
  const [vScrollbarTop, setVScrollbarTop] = useState(0);

  // 滚动条相关状态
  const [scrollLeft, setScrollLeft] = useState(0);
  const [containerWidth, setContainerWidth] = useState(0);
  const [containerHeight, setContainerHeight] = useState(0);
  const containerRef = useRef<HTMLDivElement>(null);

  // 切换展开/折叠状态
  const toggleExpand = useCallback((taskId: string) => {
    setExpandedTasks((prev) => {
      const newExpanded = new Set(prev);
      if (newExpanded.has(taskId)) {
        newExpanded.delete(taskId);
      } else {
        newExpanded.add(taskId);
      }
      return newExpanded;
    });
  }, []);

  // 初始化任务数据
  useEffect(() => {
    setTasks(taskList);
    const initialExpanded = getInitialExpandedTasks(taskList);
    setExpandedTasks(initialExpanded);
  }, [taskList]);

  // 更新扁平化任务列表
  useEffect(() => {
    const flattened = flattenTasks(tasks, expandedTasks);
    setFlattenedTasks(flattened);
  }, [tasks, expandedTasks]);

  // 获取任务当前taskMode下的时间宽度
  useEffect(() => {
    const width = getTotalWidth(tasksStart, tasksEnd, taskMode);
    setTotalWidth(width);
  }, [taskMode, tasksEnd, tasksStart])

  const updateContainer = () => {
    if (containerRef.current) {
      setContainerWidth(containerRef.current.clientWidth);
      setContainerHeight(containerRef.current.clientHeight);
    }
  };

  // 监听容器宽度高度变化（添加节流优化）
  useEffect(() => {
    updateContainer();
    let resizeTimeout: NodeJS.Timeout | null = null;

    // 节流版本的resize处理函数
    const throttledResize = () => {
      if (resizeTimeout) {
        clearTimeout(resizeTimeout);
      }
      resizeTimeout = setTimeout(updateContainer, 100); // 100ms节流
    };

    window.addEventListener('resize', throttledResize, { passive: true });

    return () => {
      window.removeEventListener('resize', throttledResize);
      if (resizeTimeout) {
        clearTimeout(resizeTimeout);
      }
    };
  }, [hideTask]);

  return (
    <GanttContext.Provider
      value={{
        tasks,
        tasksStart,
        tasksEnd,
        setTasks,
        flattenedTasks,
        setFlattenedTasks,
        expandedTasks,
        setExpandedTasks,
        taskMode,
        setTaskMode,
        hideTask,
        setHideTask,
        toggleExpand,
        hoverTaskId,
        setHoverTaskId,
        scrollTop,
        setScrollTop,
        scrollLeft,
        setScrollLeft,
        containerHeight,
        containerWidth,
        totalWidth,
        setTotalWidth,
        hScrollbarWidth,
        setHScrollbarWidth,
        hScrollbarLeft,
        setHScrollbarLeft,
        vScrollbarHeight,
        setVScrollbarHeight,
        vScrollbarTop,
        setVScrollbarTop,
      }}
    >
      <div
        className={cn("flex flex-col", className)}
        ref={containerRef}
      >
        <div
          className="flex rounded-t-sm justify-between px-2 shadow-sm z-20 border"
          style={{
            height: `${GanttConsts.HEADER_HEIGHT}px`,
          }}
        >
          <TaskHeader title={title ?? "Task Gantt"} />
        </div>
        <div
          className="flex flex-row w-full border-x border-b rounded-b-sm overflow-hidden"
          style={{
            height: `calc(${containerHeight} - ${GanttConsts.HEADER_HEIGHT}px)`,
          }}
        >
          <div className="flex flex-col" style={{ width: `${GanttConsts.TASK_WIDTH}px`, display: hideTask ? 'none' : 'flex' }}>
            <Task />
          </div>
          <div className="flex flex-row items-center justify-center" style={{ width: `${hideTask ? 0 : GanttConsts.SPLIT_WIDTH}px` }}>
            <Split style={{ width: `${GanttConsts.SPLIT_WIDTH}px` }} />
          </div>
          <div className="flex overflow-hidden relative" style={{ width: `${containerWidth - (hideTask ? 0 : (GanttConsts.TASK_WIDTH + GanttConsts.SPLIT_WIDTH))}px` }}>
            <Gantt />
          </div>
        </div>
      </div>
    </GanttContext.Provider>
  );
}
